package com.ben.utils.concurrent;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class PerfThreadPools {

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();

    private static PerfThreadPoolExecutor IO_POOL;
    private static PerfThreadPoolExecutor CPU_POOL;

    private PerfThreadPools() {
    }

    public static PerfThreadPoolExecutor getIOPool() {
        if (IO_POOL == null) {
            IO_POOL = new PerfThreadPoolExecutor(
                    2 * CPU_COUNT + 1,
                    2 * CPU_COUNT + 1,
                    30,
                    TimeUnit.SECONDS,
                    new LinkedBlockingQueue<Runnable>(),
                    new PerfThreadFactory("Perf-IOThreadPool-"));
        }
        return IO_POOL;
    }

    public static PerfThreadPoolExecutor getCPUPool(boolean isRadical) {
        if (CPU_POOL == null) {
            int corePoolSize = 0;
            /*
              核心线程分配策略：
              1. 核心数在四核之下分配两个
              2. 核心数在八核之下分配四个
              3. 其他情况为核心数减一
              原因：
              需要给UI线程留有一个核心，保证UI线程有充分的时间片
              默认（保守）策略：UI线程+核心线程<总核心数，主要考虑到应用大部分存在多个线程池争抢情况
              激进策略：UI线程+核心线程=总核心数
             */
            if (CPU_COUNT <= 4) {
                corePoolSize = isRadical ? 3 : 2;
            } else if (CPU_COUNT <= 8) {
                corePoolSize = isRadical ? 6 : 4;
            } else {
                corePoolSize = CPU_COUNT - 1;
            }
            CPU_POOL = new PerfThreadPoolExecutor(
                    corePoolSize,
                    corePoolSize,
                    30,
                    TimeUnit.SECONDS,
                    new LinkedBlockingQueue<Runnable>(),
                    new PerfThreadFactory("Perf-CPUThreadPool-"));
        }
        return CPU_POOL;
    }


}
